package cn.iocoder.yudao.module.dify.util;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.*;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * 文件内容读取工具类
 * 支持从URL读取PDF和DOCX文件并提取文本内容
 */
public class FileContentReaderUtils {

    /**
     * 从URL读取文件内容并解析为文本
     *
     * @param fileUrl 文件URL地址
     * @return 提取的文本内容
     * @throws IOException IO异常
     */
    public static String readContentFromFileUrl(String fileUrl) throws IOException {
        if (fileUrl == null || fileUrl.isEmpty()) {
            throw new IllegalArgumentException("文件URL不能为空");
        }

        // 编码URL中的特殊字符
        String encodedUrl = encodeUrl(fileUrl);

        // 从URL获取文件名和扩展名
        String fileName = getFileNameFromUrl(encodedUrl);
        String fileExtension = getFileExtension(fileName).toLowerCase();

        // 下载文件内容
        byte[] fileContent = downloadFileFromUrl(encodedUrl);

        // 根据文件扩展名解析内容
        switch (fileExtension) {
            case "pdf":
                return readPdfContent(fileContent);
            default:
                throw new IllegalArgumentException("不支持的文件类型: " + fileExtension);
        }
    }

    /**
     * 编码URL中的特殊字符
     *
     * @param url 原始URL
     * @return 编码后的URL
     */
    public static String encodeUrl(String url) {
        try {
            URL originalUrl = new URL(url);
            String protocol = originalUrl.getProtocol();
            String host = originalUrl.getHost();
            int port = originalUrl.getPort();
            String path = originalUrl.getPath();
            String query = originalUrl.getQuery();

            // 对路径中的特殊字符进行编码
            String[] pathSegments = path.split("/");
            StringBuilder encodedPath = new StringBuilder();
            for (int i = 0; i < pathSegments.length; i++) {
                if (i > 0) {
                    encodedPath.append("/");
                }
                if (!pathSegments[i].isEmpty()) {
                    // 手动编码特殊字符
                    String encodedSegment = pathSegments[i]
                            .replace(" ", "%20")
                            .replace("【", "%E3%80%90")
                            .replace("】", "%E3%80%91")
                            .replace("(", "%28")
                            .replace(")", "%29");
                    encodedPath.append(encodedSegment);
                }
            }

            StringBuilder encodedUrl = new StringBuilder();
            encodedUrl.append(protocol).append("://").append(host);
            if (port != -1) {
                encodedUrl.append(":").append(port);
            }
            encodedUrl.append(encodedPath);

            if (query != null) {
                encodedUrl.append("?").append(query);
            }

            return encodedUrl.toString();
        } catch (Exception e) {
            // 如果编码失败，返回原始URL
            return url;
        }
    }

    /**
     * 从URL中提取文件名
     *
     * @param url 文件URL
     * @return 文件名
     */
    private static String getFileNameFromUrl(String url) {
        return url.substring(url.lastIndexOf('/') + 1);
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName 文件名
     * @return 文件扩展名
     */
    private static String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
    }

    /**
     * 从URL下载文件内容
     *
     * @param fileUrl 文件URL
     * @return 文件字节数组
     * @throws IOException IO异常
     */
    public static byte[] downloadFileFromUrl(String fileUrl) throws IOException {
        URL url = new URL(fileUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; FileDownloader/1.0)");
        connection.setConnectTimeout(30000); // 30秒连接超时
        connection.setReadTimeout(60000);    // 60秒读取超时

        try (InputStream in = connection.getInputStream()) {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = in.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            return buffer.toByteArray();
        } finally {
            connection.disconnect();
        }
    }

    /**
     * 读取PDF文件内容
     *
     * @param fileContent PDF文件字节数组
     * @return 提取的文本内容
     * @throws IOException IO异常
     */
    private static String readPdfContent(byte[] fileContent) throws IOException {
        try (PDDocument document = PDDocument.load(fileContent)) {
            PDFTextStripper pdfStripper = new PDFTextStripper();
            return pdfStripper.getText(document);
        }
    }

    /**
     * 判断URL对应的文件是否为PDF格式
     *
     * @param fileUrl 文件URL
     * @return 是否为PDF文件
     */
    public static boolean isPdfFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        String fileName = getFileNameFromUrl(fileUrl);
        String fileExtension = getFileExtension(fileName).toLowerCase();
        return "pdf".equals(fileExtension);
    }

    /**
     * 判断URL对应的文件是否为DOCX格式
     *
     * @param fileUrl 文件URL
     * @return 是否为DOCX文件
     */
    public static boolean isDocxFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        String fileName = getFileNameFromUrl(fileUrl);
        String fileExtension = getFileExtension(fileName).toLowerCase();
        return "docx".equals(fileExtension);
    }


    /**
     * 翻译DOCX文档内容
     *
     * @param document 原始XWPFDocument对象
     * @return 翻译后的XWPFDocument对象
     * @throws IOException IO异常
     */
    public static XWPFDocument translateDocxContent(XWPFDocument document) throws IOException {
        // 克隆原始文档以保留格式
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        document.write(bos);
        XWPFDocument translatedDocument = new XWPFDocument(new ByteArrayInputStream(bos.toByteArray()));

        // 1. 遍历并翻译段落
        List<XWPFParagraph> paragraphs = translatedDocument.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            translateParagraph(paragraph);
        }

        // 2. 遍历并翻译表格内容
        List<XWPFTable> tables = translatedDocument.getTables();
        for (XWPFTable table : tables) {
            translateTable(table);
        }

        return translatedDocument;
    }

    /**
     * 翻译段落内容
     *
     * @param paragraph 段落对象
     */
    private static void translateParagraph(XWPFParagraph paragraph) {
        // 获取段落中的所有文本块
        List<XWPFRun> runs = paragraph.getRuns();
        if (runs != null && !runs.isEmpty()) {
            StringBuilder paragraphText = new StringBuilder();

            // 提取段落全部文本
            for (XWPFRun run : runs) {
                paragraphText.append(run.getText(0));
            }

            String originalText = paragraphText.toString();
            if (!originalText.trim().isEmpty()) {
                // 这里调用翻译API进行翻译
                String translatedText = translateText(originalText);

                // 清除原内容并设置翻译后的内容
                for (int i = 0; i < runs.size(); i++) {
                    if (i == 0) {
                        runs.get(i).setText(translatedText, 0);
                    } else {
                        runs.get(i).setText("", 0);
                    }
                }
            }
        }
    }

    /**
     * 翻译表格内容
     *
     * @param table 表格对象
     */
    private static void translateTable(XWPFTable table) {
        List<XWPFTableRow> rows = table.getRows();
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                // 遍历单元格中的段落
                List<XWPFParagraph> cellParagraphs = cell.getParagraphs();
                for (XWPFParagraph cellParagraph : cellParagraphs) {
                    translateParagraph(cellParagraph);
                }
            }
        }
    }

    /**
     * 文本翻译方法（示例实现）
     * 实际使用中应替换为真实的翻译API调用
     *
     * @param text 待翻译的文本
     * @return 翻译后的文本
     */
    private static String translateText(String text) {
        // 1. 百度翻译API
        // 2. 谷歌翻译API
        // 3. 有道翻译API
        // 4. 自建翻译服务

        // 示例：简单模拟翻译（实际应调用翻译API）
        if (text != null && !text.trim().isEmpty()) {
            // 只有包含中文才进行翻译
            if (containsChinese(text)) {
                // 这里调用实际的翻译API
                return "[Translated] " + text; // 示例返回
            }
            try {
                // 调用翻译API的示例（需要根据具体API调整）
                String translated = text;
                return translated;
            } catch (Exception e) {
                // 翻译失败时返回原文
                return text;
            }
            // 临时返回原文 + [Translated] 标记作为示例
            // return "" + text;
        }
        return text;
    }

    /**
     * 保存翻译后文档的方法
     *
     * @param document   翻译后的XWPFDocument对象
     * @param outputPath 输出文件路径
     * @throws IOException IO异常
     */
    public static void saveTranslatedDocument(XWPFDocument document, String outputPath) throws IOException {
        try (FileOutputStream out = new FileOutputStream(outputPath)) {
            document.write(out);
        }
    }

    /**
     * 从URL读取并翻译DOCX文件
     *
     * @param fileUrl    文件URL地址
     * @param outputPath 输出文件路径
     * @throws IOException IO异常
     */
    public static void translateDocxFromFileUrl(String fileUrl, String outputPath) throws IOException {
        // 编码URL中的特殊字符
        String encodedUrl = encodeUrl(fileUrl);

        // 下载文件内容
        byte[] fileContent = downloadFileFromUrl(encodedUrl);

        // 加载DOCX文档
        try (XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(fileContent))) {
            // 翻译文档
            XWPFDocument translatedDocument = translateDocxContent(document);

            // 保存翻译后的文档
            saveTranslatedDocument(translatedDocument, outputPath);
        }
    }

    /**
     * 判断文本内容是否包含汉字字符（基本汉字范围）
     *
     * @param text 待检测的文本
     * @return 如果包含汉字字符返回true，否则返回false
     */
    public static boolean containsChinese(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }

        // 只检查基本汉字范围，避免误判其他字符
        // \u4e00-\u9fff 覆盖了绝大部分常用汉字
        return text.matches(".*[\\u4e00-\\u9fff]+.*");
    }

    /**
     * 将XWPFDocument转换为字节数组
     *
     * @param document XWPFDocument对象
     * @return 字节数组
     * @throws IOException IO异常
     */
    public static byte[] documentToByteArray(XWPFDocument document) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            document.write(bos);
            return bos.toByteArray();
        }
    }

    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\xiezheng\\Desktop\\2022工\\puyuan-test\\翻译\\【测试PDF】风险管理报告 v8(5).pdf");
        //读取pdf文件
        //保留格式并且替换内容
    }

}
